﻿using ArduinoSharp.Lib;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ADCtestApp
{
    
    public delegate void SerialNewDataHandler(object sender, ArduinoSerialEventArgs e);
    /// <summary>
    /// Interaction logic for serialPortUC.xaml
    /// </summary>
    public partial class serialPortUC : UserControl
    {
        
        private SerialPort comport = new SerialPort("COM1", 115200, Parity.None, 8, StopBits.One);
        

        public event SerialNewDataHandler onNewDataArived;

        public serialPortUC()
        {
            InitializeComponent();
            InitialiseControlValues();
            this.comport.ReadTimeout = 500;
            this.comport.WriteTimeout = 500;

        }

        public void sendData(string data)
        {
            if (this.comport.IsOpen)
            {
                this.comport.WriteLine(data);
            }
        }

        private void InitialiseControlValues()
        {


            //fill Ports in combobox
            PortNameCB.Items.Clear();
            SerialPort.GetPortNames().ToList()
                .ForEach(item => PortNameCB.Items.Add(item));

            //fill Parity in combobox
            ParityCB.Items.Clear();
            Enum.GetNames(typeof(Parity)).ToList()
                .ForEach(item => ParityCB.Items.Add(item));
            ParityCB.SelectedIndex = 0;

            //fill StopBits in combobox
            Enum.GetNames(typeof(StopBits)).ToList()
                .ForEach(item => StopBitsCB.Items.Add(item));
            StopBitsCB.SelectedIndex = 1;

            //fill DataBits in combobox
            var databits = new object[] {
            "7",
            "8",
            "9"};
            databits.ToList()
               .ForEach(item => DataBitsCB.Items.Add(item));
            DataBitsCB.SelectedIndex = 1;

            //fill Handshake in combobox
            Enum.GetNames(typeof(Handshake)).ToList()
                .ForEach(item => HandshakeCB.Items.Add(item));
            HandshakeCB.SelectedIndex = 0;


            //fill baudrates in combobox
            var baudrates = new object[] {
            "1200",
            "2400",
            "4800",
            "9600",
            "14400",
            "19200",
            "28800",
            "38400",
            "57600",
            "115200",
            "230400",
            "460800",
            "921600",
            "1328400"};
            baudrates.ToList().ForEach(item => BaudrateCB.Items.Add(item));
            BaudrateCB.SelectedIndex = 9;
            if (PortNameCB.Items.Count > 0) PortNameCB.SelectedIndex = 0;
            else
            {
                //MessageBox.Show(this, "There are no COM Ports detected on this computer.\nPlease install a COM Port and restart this app. No COM Ports Installed");

            }

            this.comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

        }

        private void OpenBT_Click(object sender, RoutedEventArgs e)
        {

            if (this.comport.IsOpen)
            {
                this.comport.Close();
                OpenBt.Content = "Open Port";
            }
            else
            {
                try
                {
                    // Set the port's settings
                    this.comport.BaudRate = int.Parse(BaudrateCB.Text);
                    this.comport.DataBits = int.Parse(DataBitsCB.Text);
                    this.comport.StopBits = (StopBits)Enum.Parse(typeof(StopBits), StopBitsCB.Text);
                    this.comport.Parity = (Parity)Enum.Parse(typeof(Parity), ParityCB.Text);
                    this.comport.PortName = PortNameCB.Text;

                    // Open the port
                    this.comport.Open();
                    OpenBt.Content = "Close Port";
                }
                catch (ArgumentException) { MessageBox.Show("Nesprávné nastavení seriového portu.", "Non valid Serial port set up."); }
            }
        }

        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // This method will be called when there is data waiting in the port's buffer
            // Read all the data waiting in the buffer and pasrse it

            /* http://forums.microsoft.com/MSDN/ShowPost.aspx?PageIndex=2&SiteID=1&PostID=293187
             * You would need to use Control.Invoke() to update the GUI controls
             * because unlike Windows Forms events like Button.Click which are processed 
             * in the GUI thread, SerialPort events are processed in a non-GUI thread 
             * (more precisely a ThreadPool thread). 
             */
            string inString;
            inString = this.comport.ReadLine();
            if (inString != null && inString.StartsWith("{") && inString.EndsWith("}"))
            {
                var sd =new ArduinoSerialData(inString);
                var ev = new ArduinoSerialEventArgs(sd);
                if (onNewDataArived != null)
                {
                    onNewDataArived(this, ev);
                }
                //MessageBox.Show(sd.ToString());
            }

        }

        protected virtual void Dispose(bool disposing)
        {
            this.comport.Close();
           // NewLineArived(SerialEventArgs.Empty);
        }
    }


    
}
